/*
 * AD9954 IO Driver Header file
 */

#ifndef _HW_AD9954_H_
#define _HW_AD9954_H_

// I using this unfriendly way to make an convenient pins connection.
#define AD9954_SPI_PORT     SSP[1]
#define AD9954_CTL_PORT_AND_POS_IOSYNC   2,4
#define AD9954_CTL_PORT_AND_POS_PWRDWN   2,5
#define AD9954_CTL_PORT_AND_POS_OSK      2,6
#define AD9954_CTL_PORT_AND_POS_UPDATE   2,7
#define AD9954_CTL_PORT_AND_POS_PS1      2,8
#define AD9954_CTL_PORT_AND_POS_RST      2,9
#define AD9954_CTL_PORT_AND_POS_PS0      2,10

//#define AD9954_CTL_UPDATE_IOCON     LPC_IOCON->PIO1_6
//#define AD9954_CTL_PS1_IOCON        LPC_IOCON->PIO1_11
//#define AD9954_CTL_OSK_IOCON        LPC_IOCON->PIO1_4
//#define AD9954_CTL_IOSYNC_IOCON     LPC_IOCON->PIO0_11
//#define AD9954_CTL_PWRDWN_IOCON     LPC_IOCON->PIO1_2
//#define AD9954_CTL_RST_IOCON        LPC_IOCON->PIO1_1
//#define AD9954_CTL_PS0_IOCON        LPC_IOCON->PIO1_0

enum AD9954_Register {
    AD9954_CFR1  = 0x00,
    AD9954_CFR2  = 0x01,
    AD9954_ASF   = 0x02,
    AD9954_ARR   = 0x03,
    AD9954_FTW0  = 0x04,
    AD9954_POW0  = 0x05,
    AD9954_FTW1  = 0x06,
    AD9954_RSCW0 = 0x07,
    AD9954_NLSCW = 0x07,        // multifunctional register
    AD9954_RSCW1 = 0x08,
    AD9954_PLSCW = 0x08,        // multifunctional register
    AD9954_RSCW2 = 0x09,
    AD9954_RSCW3 = 0x0A,
    AD9954_REG_COUNT
};

// the register size array, contains size of 11 register.
const static uint32_t sizeofRegister[AD9954_REG_COUNT] = {
4, 3, 2, 1, 4, 2, 4, 5, 5, 5, 5
};

/*
 * this is a register with dynamic size, so I'm not putting it in the AD9954_Register.
 */
#define AD9954_RAM  0x0B

/*
typedef struct
{
	union{
		struct{
			volatile uint32_t RESERVED0					:1;
			volatile uint32_t SYNC_CLK_DISA				:1;
			volatile uint32_t LINEAR_SWEEP_DOWELL		:1;
			volatile uint32_t EXTERNAL_PWR_DOWN_MODE	:1;
			volatile uint32_t CLK_INPUT_PWR_DOWN		:1;
			volatile uint32_t DAC_PWR_DOWN				:1;
			volatile uint32_t COMP_PWR_DOWN				:1;
			volatile uint32_t DIGITAL_PWR_DOWN			:1;
			volatile uint32_t LSB_FIRST					:1;
			volatile uint32_t SDIO_INPUT_ONLY			:1;
			volatile uint32_t CLR_PHASE_ACC				:1;
			volatile uint32_t SINE_COSINE_SEL			:1;
			volatile uint32_t AUTO_CLR_PHASE_ACC		:1;
			volatile uint32_t AUTO_CLR_FREQ_ACC			:1;
			volatile uint32_t SRR_LOAD_EN				:1;
			volatile uint32_t RESERVED1					:1;
			volatile uint32_t RESERVED2					:1;
			volatile uint32_t RESERVED3					:1;
			volatile uint32_t RESERVED4					:1;
			volatile uint32_t RESERVED5					:1;
			volatile uint32_t LINEAR_SWEEP_EN			:1;
			volatile uint32_t SW_MAN_SYNC				:1;
			volatile uint32_t AUTO_SYNC_EN				:1;
			volatile uint32_t AUTO_OSK_EN				:1;
			volatile uint32_t OSK_EN					:1;
			volatile uint32_t LOAD_ARR_CTL				:1;
			volatile uint32_t INT_PROFILE				:3;
			volatile uint32_t RAM_DESTINATION			:1;
			volatile uint32_t RAM_EN					:1;
		}BITS;
		volatile uint32_t WORD;
	}CFR1;

	union{
			struct{
				volatile uint32_t CHG_PUMP_CURRENT			:2;
				volatile uint32_t VCO_RANGE					:1;
				volatile uint32_t REFCLK_MULTIPLIER			:5;
				volatile uint32_t RESERVED0					:1;
				volatile uint32_t XTAL_OUT_EN				:1;
				volatile uint32_t HW_MAN_SYNC_EN			:1;
				volatile uint32_t HS_SYNC_EN				:1;
				volatile uint32_t RESERVED1					:20;
			}BITS;
			volatile uint32_t WORD;
		}CFR2;

	union{
			struct{
				volatile uint32_t AMP_SCALE_FACTOR			:14;
				volatile uint32_t AUTO_RAMP_SPD_CTL			:2;
				volatile uint32_t RESERVED					:16;
			}BITS;
			volatile uint32_t WORD;
		}ASF;

	union{
			struct{
				volatile uint32_t AMP_RAMP_RATE				:8;
				volatile uint32_t RESERVED					:24;
			}BITS;
			volatile uint32_t WORD;
		}ARR;

	union{
			struct{
				volatile uint32_t FREQ_TUNING_WORD			:32;
			}BITS;
			volatile uint32_t WORD;
		}FTW0;

	union{
			struct{
				volatile uint32_t PHASE_OFFSET_WORD			:14;
				volatile uint32_t RESERVED					:18;
			}BITS;
			volatile uint32_t WORD;
		}POW0;

	union{
			struct{
				volatile uint32_t FREQ_TUNING_WORD			:32;
			}BITS;
			volatile uint32_t WORD;
		}FTW1;

	union{
			struct{
				volatile uint32_t RAM_SEG0_BEGIN_ADDRH		:4;
				volatile uint32_t NODWELL_ACTIVE			:1;
				volatile uint32_t RAM_SEG0_MODE_CTL			:3;
				volatile uint32_t RAM_SEG0_FINAL_ADDRH		:2;
				volatile uint32_t RAM_SEG0_BEGIN_ADDRL		:6;
				volatile uint32_t RAM_SEG0_FINAL_ADDRL		:8;
				volatile uint32_t RAM_SEG0_ADDR_RAMP_RATE	:16;
				volatile uint32_t RESERVED					:24;
			}BITS;
			volatile uint64_t WORD;
		}RSCW0;

	union{
			struct{
				volatile uint32_t RAM_SEG1_BEGIN_ADDRH		:4;
				volatile uint32_t NODWELL_ACTIVE			:1;
				volatile uint32_t RAM_SEG1_MODE_CTL			:3;
				volatile uint32_t RAM_SEG1_FINAL_ADDRH		:2;
				volatile uint32_t RAM_SEG1_BEGIN_ADDRL		:6;
				volatile uint32_t RAM_SEG1_FINAL_ADDRL		:8;
				volatile uint32_t RAM_SEG1_ADDR_RAMP_RATE	:16;
				volatile uint32_t RESERVED					:24;
			}BITS;
			volatile uint64_t WORD;
		}RSCW1;

	union{
			struct{
				volatile uint32_t RAM_SEG2_BEGIN_ADDRH		:4;
				volatile uint32_t NODWELL_ACTIVE			:1;
				volatile uint32_t RAM_SEG2_MODE_CTL			:3;
				volatile uint32_t RAM_SEG2_FINAL_ADDRH		:2;
				volatile uint32_t RAM_SEG2_BEGIN_ADDRL		:6;
				volatile uint32_t RAM_SEG2_FINAL_ADDRL		:8;
				volatile uint32_t RAM_SEG2_ADDR_RAMP_RATE	:16;
				volatile uint32_t RESERVED					:24;
			}BITS;
			volatile uint64_t WORD;
		}RSCW2;

	union{
			struct{
				volatile uint32_t RAM_SEG3_BEGIN_ADDRH		:4;
				volatile uint32_t NODWELL_ACTIVE			:1;
				volatile uint32_t RAM_SEG3_MODE_CTL			:3;
				volatile uint32_t RAM_SEG3_FINAL_ADDRH		:2;
				volatile uint32_t RAM_SEG3_BEGIN_ADDRL		:6;
				volatile uint32_t RAM_SEG3_FINAL_ADDRL		:8;
				volatile uint32_t RAM_SEG3_ADDR_RAMP_RATE	:16;
				volatile uint32_t RESERVED					:24;
			}BITS;
			volatile uint64_t WORD;
		}RSCW3;
}AD9954_REG;
*/

/*
#ifndef AD9954
	#define AD9954 ((AD9954_REG *) AD9954_BASE)
#endif
*/

void ad9954_io_init(void);
void ad9954_hwrst(void);
void ad9954_update(void);
void ad9954_pwrdwn_set(bool set);
void ad9954_iosync(void);
void ad9954_osk_set(bool set);
void ad9954_ps0_set(bool set);
void ad9954_ps1_set(bool set);

void ad9954_register_write(enum AD9954_Register reg, uint8_t *data);
void ad9954_register_read(enum AD9954_Register reg, uint8_t *data);
void ad9954_ram_write(uint32_t *data, uint32_t len);
void ad9954_ram_read(uint32_t *data, uint32_t len);

#endif /* _HW_AD9954_H_ */
